package com.imooc.coupon.config;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 异步任务线程池配置
 * Created By TINY
 * Create Time 2020/2/9 - 18:31
 **/
@Configuration
@EnableAsync
@Slf4j
public class AsyncPoolConfig implements AsyncConfigurer {

    @Override
    @Bean("asyncExecutor")
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

        // 线程池核心线程数
        executor.setCorePoolSize(10);
        // 线程池最大容量
        executor.setMaxPoolSize(20);
        // 线程池队列容量
        executor.setQueueCapacity(20);
        // 超过核心线程数的线程的最大存活时间
        executor.setKeepAliveSeconds(60);
        // 线程名前缀
        executor.setThreadNamePrefix("ImoocAsync_");

        // 等待所有任务执行完后关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 线程最大等待时间
        executor.setAwaitTerminationSeconds(60);

        // 线程池拒绝策略
        executor.setRejectedExecutionHandler(
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        // 初始化线程
        executor.initialize();

        return executor;
    }

    /**
     * 异步任务（无返回值）异常处理器
     * @return 异步任务异常处理器
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (throwable, method, objects) -> {

            throwable.printStackTrace();

            log.error("AsyncError: {}, method: {}, param: {}",
                    throwable.getMessage(), method.getName(),
                    JSON.toJSONString(objects));


        };
    }
}
